<script setup lang="ts">
import {ref, watch, onMounted} from "vue";
//导入图标
import {
  Search,
  RefreshRight,
  Plus,
  EditPen,
  Delete,
  DocumentCopy,
  UploadFilled
} from '@element-plus/icons-vue'
import service from "@/utils/request.ts";
import type {ElTable} from "element-plus";

const props = withDefaults(defineProps<{
  title?: string | null,
  rowKey?: string | null,
  searchInfo?: {
    label: string,
    key: string,
    value: string,
    type?: 'input' | 'select' | undefined,
    options?: { label: string, value: string }[] | undefined
  }[],
  apiMethod?: string
  apiPath?: string
  pageable?: boolean
  pageParams?: {
    pageNum: string,
    pageSize: string
  },
  dataIdKey?: string
  btnShow?: {
    add?: boolean,
    edit?: boolean,
    delete?: boolean,
    export?: boolean
    import?: boolean
  },
  withoutBorder?: boolean
  tableStyle?: object | null
}>(), {
  title: null,
  rowKey: null,
  searchInfo: () => [],
  apiMethod: () => 'get',
  apiPath: () => '',
  pageable: () => true,
  pageParams: () => ({
    pageNum: 'pageNum',
    pageSize: 'pageSize'
  }),
  dataIdKey: () => 'id',
  btnShow: () => ({
    add: true,
    edit: true,
    delete: true,
    export: true,
    import: true
  }),
  withoutBorder: () => true,
  tableStyle: null,
})


const searchInfo = ref<{
  label: string,
  key: string,
  value: string,
  type?: 'input' | 'select',
  options?: { label: string, value: string }[]
}[] | undefined>(props.searchInfo)

const loading = ref<boolean>(true)
const selectedItems = ref<boolean>(false)
const multipleSelection = ref<never[]>([])
const multipleTableRef = ref<InstanceType<typeof ElTable>>()

const tableData = ref([])
const total = ref<number>(0)
const currentPage = ref<number>(1)
const pageSize = ref<number>(10)

const handleSizeChange = (val: number) => {
  pageSize.value = val
  queryData()
}
const handleCurrentChange = (val: number) => {
  currentPage.value = val
  queryData()
}
const handleSelectionChange = (val: never[]) => {
  multipleSelection.value = val
}
watch(multipleSelection, (val) => {
  selectedItems.value = val.length > 0
  emit('multipleSelection', multipleSelection?.value || [])
})
const handleClearSelection = () => {
  console.log('handleClearSelection')
  selectedItems.value = false
  multipleSelection.value = []
  multipleTableRef.value!.clearSelection()
}


const queryData = () => {
  const params = {}
  if (searchInfo.value) {
    searchInfo.value.forEach(item => {
      params[item.key] = item.value;
    })
  }

  if (props.pageable) {
    params[props?.pageParams?.pageNum ? props?.pageParams?.pageNum : 'pageNum'] = currentPage.value;
    params[props?.pageParams?.pageSize ? props?.pageParams?.pageSize : 'pageSize'] = pageSize.value;
  }

  if (props.apiPath) {
    const apiMethod = props.apiMethod || 'get'
    service.request({
      url: props.apiPath,
      method: apiMethod,
      params: apiMethod === 'get' ? params : null,
      data: apiMethod === 'post' ? params : null
    }).then((res) => {
      console.log(res)
      if (props.pageable) {
        tableData.value = res.data.records
        total.value = res.data.total
      } else {
        tableData.value = res.data
      }
    }).finally(() => {
      loading.value = false
    })
  }
}
const handleSearch = () => {
  currentPage.value = 1
  queryData()
}
const resetSearchInfo = () => {
  if (searchInfo.value) {
    searchInfo.value.forEach((item) => {
      item.value = ''
    })
    handleSearch()
  }
}

onMounted(() => {
  queryData()
})
const emit = defineEmits<{
  (e: 'handleBtnClick', key: 'add' | 'edit' | 'delete' | 'export' | 'import' | string, data: any[] | null): void;
  (e: 'multipleSelection', data: never[]): void;
}>();
const handleBtnClick = (key: string) => {
  emit('handleBtnClick', key, multipleSelection?.value || null)
}

defineExpose({
  tableData,
  multipleSelection,
  queryData, handleClearSelection
})
</script>

<template>
  <div class="app-table" :style="{
    margin: props.withoutBorder ? '' : '0',
  }">
    <div v-if="searchInfo && searchInfo?.length > 0" class="app-table-search-bar" :style="{
    boxShadow: props.withoutBorder ? '' : 'none',
    marginBottom: props.withoutBorder ? '' : '0',
    paddingBottom: props.withoutBorder ? '' : '0',
  }">
      <div v-for="item in searchInfo" :key="item.key">
        <span class="app-table-search-bar-label">{{ item.label }}</span>
        <el-input v-if="item?.type == undefined || item?.type === 'input'"
                  :placeholder="`请输入${item.label}`"
                  v-model="item.value" class="app-table-search-bar-input"></el-input>
        <el-select v-if="item.type === 'select'" :placeholder="`请选择${item.label}`"
                   v-model="item.value" class="app-table-search-bar-input">
          <el-option v-for="item2 in item?.options" :key="item2.value" :label="item2.label"
                     :value="item2.value">
          </el-option>
        </el-select>
      </div>

      <div>
        <el-button type="primary" :icon="Search" @click="handleSearch">搜索</el-button>
        <el-button :icon="RefreshRight" @click="resetSearchInfo">重置</el-button>
      </div>
    </div>

    <div class="app-table-main" :style="{
    boxShadow: props.withoutBorder ? '' : 'none',
  }">


      <div v-if="props.title" class="app-table-title">{{ props.title }}</div>

      <div class="app-table-action-bar">
        <el-button @click="handleBtnClick('add')" v-if="props?.btnShow?.add" size="small" plain
                   :icon="Plus"
                   type="primary">创建
        </el-button>
        <el-button @click="handleBtnClick('edit')" v-if="props?.btnShow?.edit"
                   :disabled="multipleSelection?.length !== 1" size="small" plain :icon="EditPen"
                   type="warning">修改
        </el-button>
        <el-button @click="handleBtnClick('delete')" v-if="props?.btnShow?.delete"
                   :disabled="!selectedItems"
                   size="small" plain :icon="Delete" type="danger">删除
        </el-button>
        <el-button @click="handleBtnClick('export')" v-if="props?.btnShow?.export" size="small"
                   plain
                   :icon="UploadFilled" type="info">导出
        </el-button>
        <el-button @click="handleBtnClick('import')" v-if="props?.btnShow?.import" size="small"
                   plain
                   :icon="DocumentCopy" type="info">导入
        </el-button>
        <slot name="actionBar"></slot>
      </div>
      <div class="app-table-content">
        <el-table v-loading="loading" :data="tableData"
                  ref="multipleTableRef"
                  style="width: 100%"
                  :style="props.tableStyle"
                  default-expand-all
                  :row-key="props.rowKey"
                  @selection-change="handleSelectionChange" border stripe>
          <el-table-column type="selection" width="40"/>
          <slot name="tableColumn"></slot>
        </el-table>
      </div>
      <div class="app-table-page">
        <el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize"
                       :page-sizes="[10, 20, 50, 100, 200, 500, 1000]" :disabled="false"
                       :background="true"
                       layout="total, sizes, prev, pager, next, jumper" :total="total"
                       @size-change="handleSizeChange"
                       :hide-on-single-page="!props.pageable"
                       @current-change="handleCurrentChange">
        </el-pagination>
      </div>
    </div>
  </div>

</template>

<style>

</style>
